library IEEE;
use IEEE.std_logic_1164.all;


entity controller is
	port (	clk			: in	std_logic;
		reset			: in	std_logic;

		sensor_l		: in	std_logic;
		sensor_m		: in	std_logic;
		sensor_r		: in	std_logic;

		count_in		: in	std_logic_vector (19 downto 0);
		count_reset		: out	std_logic;

		motor_l_reset		: out	std_logic;
		motor_l_direction	: out	std_logic;

		motor_r_reset		: out	std_logic;
		motor_r_direction	: out	std_logic
	);
end entity controller;

architecture behavioural of controller is
    
       type controller_state is (mapping, crossing, left, scanning, sharp_left, right, driving, sharp_right, searching);

       signal state, new_state:  controller_state;
       signal sensor: std_logic_vector(2 downto 0);
       
begin
    sensor <= sensor_l & sensor_m & sensor_r;
    
    process (clk)
        begin
               if (rising_edge (clk)) then
                   if (reset = '1') then
                            state <= mapping;
                   else
                            state <= new_state;
                   end if;
               end if;
        end process;
                
    process (state, sensor)
      begin
        case state is
          when mapping =>
              motor_l_reset   <= '1';
              motor_l_direction <= '0';
              motor_r_reset   <= '1';
              motor_r_direction <= '0';
                       
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
							    new_state   <= mapping;
              end if;
                    
          when driving =>
              motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
							   new_state   <= mapping;
              end if;
						 
					when crossing =>
							motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
									new_state   <= mapping;
              end if;
							  
					when scanning =>
							motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
									new_state   <= mapping;
              end if;
							  
					when searching =>
							motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
									new_state   <= mapping;
              end if;
							  
					when sharp_left =>
							motor_l_reset   <= '0';
              motor_l_direction <= '0';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
									new_state   <= mapping;
              end if;
							 
					when left =>
							motor_l_reset   <= '1';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
									new_state   <= mapping;
              end if;
							  
					when sharp_right =>
							motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '0';
              motor_r_direction <= '0';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
              elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
							    new_state   <= mapping;
          end if;
							  
					when right =>
							motor_l_reset   <= '0';
              motor_l_direction <= '1';
              motor_r_reset   <= '1';
              motor_r_direction <= '1';
                              
              if (sensor = "000") then
                  new_state   <= crossing;
              elsif (sensor = "001") then
                  new_state   <= left;
							elsif (sensor = "010") then
                  new_state   <= scanning;
							elsif (sensor = "011") then
                  new_state   <= sharp_left;
							elsif (sensor = "100") then
                  new_state   <= right;
							elsif (sensor = "101") then
                  new_state   <= driving;
							elsif (sensor = "110") then
                  new_state   <= sharp_right;
							elsif (sensor = "111") then
                  new_state   <= searching;
							else
							    new_state   <= mapping;
              end if;
      end case;
    end process;
end architecture behavioural;
           